import React, {useCallback, useEffect, useMemo, useState} from 'react'
import {Button, Card, Descriptions, Form, Input, message, Radio, Select, Space, Switch, Table, Tag} from 'antd'
import {CloudServerOutlined, DatabaseOutlined, EditOutlined, LinkOutlined, ReloadOutlined} from '@ant-design/icons'
import type {CatalogSaveVo, CatalogVo, Database} from '@/types/source'
import {sourceApi} from '@/services/api/source'

interface Props {
    catalogName: string
    onUpdated?: () => void
}

export default function CatalogPanel({catalogName, onUpdated}: Props) {
    const [loadingCatalog, setLoadingCatalog] = useState(false)
    const [loadingDB, setLoadingDB] = useState(false)
    const [catalog, setCatalog] = useState<CatalogVo | null>(null)
    const [databases, setDatabases] = useState<Database[]>([])
    const [dbSearch, setDbSearch] = useState<string>('')
    const [editing, setEditing] = useState(false)
    const [saving, setSaving] = useState(false)
    const [form] = Form.useForm<CatalogSaveVo>()
    const [testing, setTesting] = useState<{ server?: boolean; jdbc?: boolean; doris?: boolean }>({})
    const [syncing, setSyncing] = useState(false)
    const [enabling, setEnabling] = useState(false)
    const [dbToggling, setDbToggling] = useState<Record<string, boolean>>({})
    const [editingTesting, setEditingTesting] = useState<{ server?: boolean; jdbc?: boolean; doris?: boolean }>({})

    // 数据库启用开关
    const toggleDatabaseEnabled = useCallback(async (record: any, checked: boolean) => {
        const dbName = record?.name ?? record?.databaseName
        if (!dbName) {
            message.error('无法识别数据库名称')
            return
        }
        setDbToggling((m) => ({...m, [dbName]: true}))
        try {
            await sourceApi.setDatabaseEnabled(catalogName, dbName, checked)
            message.success(checked ? '数据库已启用' : '数据库已禁用')
            // 乐观更新当前行状态
            setDatabases((prev) => prev.map((d: any) => {
                const name = d?.name ?? d?.databaseName
                if (name === dbName) return {...d, enabled: checked}
                return d
            }))
        } catch (e) {
            console.error(e)
            message.error('更新数据库启用状态失败')
        } finally {
            setDbToggling((m) => ({...m, [dbName]: false}))
        }
    }, [catalogName])

    // 根据返回结果动态生成数据库列表列定义
    const buildDatabaseColumns = useCallback((list: any[]) => {
        const keys = Array.from(new Set(list.flatMap((it) => Object.keys(it || {}))))
        const columns: any[] = []

        // 名称优先（兼容后端可能使用 databaseName 字段）
        if (keys.includes('name') || keys.includes('databaseName')) {
            columns.push({
                title: '数据库',
                dataIndex: 'name',
                render: (_: any, record: any) => record?.name ?? record?.databaseName ?? '-',
            })
        }

        // 已知字段的友好展示
        const known: string[] = []
        if (keys.includes('enabled')) {
            known.push('enabled')
            columns.push({
                title: '启用',
                dataIndex: 'enabled',
                render: (v: boolean, record: any) => {
                    const dbName = record?.name ?? record?.databaseName
                    const loading = dbName ? dbToggling[dbName] : false
                    return (
                        <Switch
                            checked={!!v}
                            loading={!!loading}
                            onChange={(checked) => toggleDatabaseEnabled(record, checked)}
                            size="small"
                        />
                    )
                },
            })
        }
        if (keys.includes('systemCode') || keys.includes('defaultSystemCode')) {
            known.push('systemCode')
            known.push('defaultSystemCode')
            columns.push({
                title: '系统编码',
                dataIndex: 'systemCode',
                render: (_: any, record: any) => (record?.systemCode ?? record?.defaultSystemCode ?? '-') as any,
            })
        }
        if (keys.includes('version')) {
            known.push('version')
            columns.push({
                title: '版本',
                dataIndex: 'version',
                render: (v: string) => v || '-',
            })
        }

        // 其他返回字段全部展示（布尔显示为标签，对象/数组以JSON字符串）
        const rest = keys.filter((k) => !['name', 'databaseName', 'base', 'dorisCatalogName', 'catalogName', ...known].includes(k))
        const titleOrderMap: Record<string, string> = {
            id: 'ID',
            databaseName: '数据库名称',
            tableCount: '表',
            viewCount: '视图',
            indexCount: '索引',
            constraintCount: '约束',
            columnCount: '列',
            statisticDt: '统计时间',
        }
        const order = Object.keys(titleOrderMap)
        const prioritized = order.filter((k) => rest.includes(k))
        const others = rest.filter((k) => !order.includes(k))
        const restOrdered = [...prioritized, ...others]
        for (const k of restOrdered) {
            const titleMap: Record<string, string> = {
                id: 'ID',
                databaseName: '数据库名称',
                defaultSystemCode: '系统编码',
                tableCount: '表',
                viewCount: '视图',
                constraintCount: '约束',
                indexCount: '索引',
                columnCount: '列',
                statisticDt: '统计时间',
            }
            columns.push({
                title: titleMap[k] || k,
                dataIndex: k,
                render: (v: any) => {
                    if (v === null || v === undefined) return '-'
                    if (typeof v === 'boolean') return v ? <Tag color="green">是</Tag> : <Tag color="red">否</Tag>
                    if (typeof v === 'object') return JSON.stringify(v)
                    return String(v)
                },
            })
        }

        return columns
    }, [toggleDatabaseEnabled, dbToggling])

    const databaseColumns = useMemo(() => buildDatabaseColumns(databases as any), [buildDatabaseColumns, databases])

    const filteredDatabases = useMemo(() => {
        if (!dbSearch) return databases
        const q = dbSearch.toLowerCase()
        return databases.filter((d: any) => {
            const name = (d?.name ?? d?.databaseName ?? '').toLowerCase()
            return name.includes(q)
        })
    }, [databases, dbSearch])

    const loadCatalog = useCallback(async () => {
        setLoadingCatalog(true)
        const localName = catalogName
        try {
            const data = await sourceApi.getCatalog(localName)
            if (catalogName !== localName) return
            setCatalog(data)
        } catch (e) {
            console.error(e)
            message.error('加载目录信息失败')
        } finally {
            setLoadingCatalog(false)
        }
    }, [catalogName])

    const loadDatabases = useCallback(async () => {
        setLoadingDB(true)
        const localName = catalogName
        try {
            const list = await sourceApi.getDatabases(localName)
            if (catalogName !== localName) return
            setDatabases(list || [])
        } catch (e) {
            console.error(e)
            message.error('加载数据库列表失败')
        } finally {
            setLoadingDB(false)
        }
    }, [catalogName])

    useEffect(() => {
        loadCatalog()
        loadDatabases()
    }, [catalogName])

    const refreshAll = useCallback(async () => {
        await Promise.all([loadCatalog(), loadDatabases()])
        onUpdated?.()
    }, [loadCatalog, loadDatabases, onUpdated])

    const handleEnable = async (enabled: boolean) => {
        setEnabling(true)
        try {
            await sourceApi.setCatalogEnabled(catalogName, enabled)
            message.success(enabled ? '目录已启动' : '目录已关闭')
            await loadCatalog()
        } catch (e) {
            console.error(e)
            message.error('更新启用状态失败')
        } finally {
            setEnabling(false)
        }
    }

    const handleSync = async () => {
        setSyncing(true)
        try {
            await sourceApi.syncCatalog(catalogName)
            message.success('目录同步已完成')
            await refreshAll()
        } catch (e) {
            console.error(e)
            message.error('目录同步失败')
        } finally {
            setSyncing(false)
        }
    }

    // 编辑态下，使用当前表单值进行连接测试
    const testEditing = async (type: 'server' | 'jdbc' | 'doris') => {
        try {
            const values = await form.validateFields()
            setEditingTesting((s) => ({ ...s, [type]: true }))
            const ok = await (
                type === 'server' ? sourceApi.testServer(values) :
                    type === 'jdbc' ? sourceApi.testJdbc(values) :
                        sourceApi.testDoris(values)
            )
            message.success(`${type.toUpperCase()} 测试${ok ? '成功' : '失败'}`)
        } catch (e) {
            console.error(e)
            message.error('测试失败，请检查必填项')
        } finally {
            setEditingTesting((s) => ({ ...s, [type]: false }))
        }
    }

    const testAndRefresh = async (type: 'server' | 'jdbc' | 'doris') => {
        setTesting((s) => ({...s, [type]: true}))
        try {
            const ok = await (
                type === 'server' ? sourceApi.testCatalogServer(catalogName) :
                    type === 'jdbc' ? sourceApi.testCatalogJdbc(catalogName) :
                        sourceApi.testCatalogDoris(catalogName)
            )
            message.success(`${type.toUpperCase()} 测试${ok ? '成功' : '失败'}`)
            await loadCatalog()
        } catch (e) {
            console.error(e)
            message.error(`${type.toUpperCase()} 测试失败`)
        } finally {
            setTesting((s) => ({...s, [type]: false}))
        }
    }

    const initialFormValues = useMemo(() => {
        if (!catalog) return undefined
        return {
            catalogName: catalog.catalogName,
            host: catalog.host,
            port: catalog.port,
            databaseType: catalog.databaseType,
            route: catalog.route,
            userName: catalog.userName,
            password: '', // 出于安全不回显
            connectType: catalog.connectType,
            dorisCatalogName: catalog.dorisCatalogName,
            defaultSystemCode: catalog.defaultSystemCode,
        } as CatalogSaveVo
    }, [catalog])

    const openEdit = () => {
        if (!catalog) return
        setEditing(true)
        form.setFieldsValue(initialFormValues)
    }

    const submitEdit = async () => {
        try {
            const values = await form.validateFields()
            setSaving(true)
            await sourceApi.saveCatalog({
                ...values,
                port: Number(values.port),
            })
            message.success('目录信息已保存')
            setEditing(false)
            await loadCatalog()
            onUpdated?.()
        } catch (e: any) {
            if (e?.errorFields) return
            console.error(e)
            message.error(e?.message || '保存失败')
        } finally {
            setSaving(false)
        }
    }

    return (
        <div style={{display: 'grid', gap: 12}} >
            {/* 操作区 */}
            <Card size="small" title={
                <Space>
                    <DatabaseOutlined/>
                    <span>目录：{catalogName}</span>
                </Space>
            } extra={
                <Space>
                    <Button size="small" icon={<ReloadOutlined/>} onClick={refreshAll}
                            loading={loadingCatalog || loadingDB}>刷新</Button>
                </Space>
            }>
                {/* 顶部操作区移除启停与同步按钮，保留刷新 */}
            </Card>

            {/* 连接状态 + 测试 */}
            <Card size="small" title={<Space><LinkOutlined/><span>连接状态</span></Space>}>
                <Space direction="vertical" size="small" style={{width: '100%'}}>
                    <Space>
                        <span>服务器连接：</span>
                        <Tag
                            color={catalog?.serverConnected ? 'green' : 'red'}>{catalog?.serverConnected ? '已连接' : '未连接'}</Tag>
                        {catalog?.serverConnectedDt && <small>最近：{catalog?.serverConnectedDt}</small>}
                        <Button size="small" onClick={() => testAndRefresh('server')}
                                loading={testing.server}>测试</Button>
                    </Space>
                    <Space>
                        <span>JDBC连接：</span>
                        <Tag
                            color={catalog?.jdbcConnected ? 'green' : 'red'}>{catalog?.jdbcConnected ? '已连接' : '未连接'}</Tag>
                        {catalog?.jdbcConnectedDt && <small>最近：{catalog?.jdbcConnectedDt}</small>}
                        <Button size="small" onClick={() => testAndRefresh('jdbc')} loading={testing.jdbc}>测试</Button>
                    </Space>
                    <Space>
                        <span>Doris连接：</span>
                        <Tag
                            color={catalog?.dorisConnected ? 'green' : 'red'}>{catalog?.dorisConnected ? '已连接' : '未连接'}</Tag>
                        {catalog?.dorisConnectedDt && <small>最近：{catalog?.dorisConnectedDt}</small>}
                        <Button size="small" onClick={() => testAndRefresh('doris')}
                                loading={testing.doris}>测试</Button>
                    </Space>
                </Space>
            </Card>

            {/* 目录信息 */}
            <Card size="small" title={<Space><EditOutlined/><span>目录信息</span></Space>}
                  extra={!editing ? <Button size="small" onClick={openEdit}>编辑</Button> : null}>
                {!editing ? (
                    <Descriptions
                        size="small"
                        column={2}
                        styles={{ label: { width: 120 }, content: { minWidth: 220 } }}
                    >
                        <Descriptions.Item label="名称*">{catalog?.catalogName}</Descriptions.Item>
                        <Descriptions.Item label="类型*">{catalog?.databaseType}</Descriptions.Item>
                        <Descriptions.Item label="主机*">{catalog?.host}</Descriptions.Item>
                        <Descriptions.Item label="端口*">{catalog?.port}</Descriptions.Item>
                        <Descriptions.Item label="路由*">{catalog?.route}</Descriptions.Item>
                        <Descriptions.Item label="用户名*">{catalog?.userName}</Descriptions.Item>
                        <Descriptions.Item label="连接类型*">{catalog?.connectType}</Descriptions.Item>
                        <Descriptions.Item label="数据库版本">{catalog?.databaseVersion || '-'}</Descriptions.Item>
                        <Descriptions.Item label="Doris Catalog 名称*">{catalog?.dorisCatalogName}</Descriptions.Item>
                        <Descriptions.Item label="默认系统编码*">{catalog?.defaultSystemCode}</Descriptions.Item>
                        <Descriptions.Item label="状态">
                            <Space>
                                {catalog?.enabled ? <Tag color="green">已启用</Tag> :
                                    <Tag color="red">未启用</Tag>}
                                <Switch
                                    size="small"
                                    checked={!!catalog?.enabled}
                                    loading={enabling}
                                    onChange={(checked) => handleEnable(checked)}
                                />
                            </Space>
                        </Descriptions.Item>
                    </Descriptions>
                ) : (
                    <>
                        <Form form={form} initialValues={initialFormValues} component={false} validateTrigger="onBlur">
                            <Descriptions
                                size="small"
                                column={2}
                                styles={{ label: { width: 120 }, content: { minWidth: 220 } }}
                            >
                                <Descriptions.Item label="名称*">
                                    <Form.Item name="catalogName" rules={[{required: true, message: '请输入目录名称'}]} style={{ margin: 0 }}>
                                        <Input size="small" placeholder="必填：目录名称"/>
                                    </Form.Item>
                                </Descriptions.Item>
                                <Descriptions.Item label="类型*">
                                    <Form.Item name="databaseType" rules={[{required: true, message: '请选择数据库类型'}]} style={{ margin: 0 }}>
                                        <Select size="small" placeholder="必填：数据库类型" options={[
                                            {label: 'MySQL', value: 'MYSQL'},
                                            {label: 'Oracle', value: 'ORACLE'},
                                            {label: 'PostgreSQL', value: 'POSTGRESQL'},
                                            {label: 'SQLServer', value: 'SQLSERVER'},
                                        ]}/>
                                    </Form.Item>
                                </Descriptions.Item>
                                <Descriptions.Item label="主机*">
                                    <Form.Item name="host" rules={[{required: true, message: '请输入主机'}]} style={{ margin: 0 }}>
                                        <Input size="small" placeholder="必填：主机"/>
                                    </Form.Item>
                                </Descriptions.Item>
                                <Descriptions.Item label="端口*">
                                    <Form.Item name="port" rules={[{required: true, message: '请输入端口'}]} style={{ margin: 0 }}>
                                        <Input size="small" type="number" placeholder="必填：端口"/>
                                    </Form.Item>
                                </Descriptions.Item>
                                <Descriptions.Item label="路由*">
                                    <Form.Item name="route" rules={[{required: true, message: '请输入路由/服务名'}]} style={{ margin: 0 }}>
                                        <Input size="small" placeholder="必填：路由/服务名"/>
                                    </Form.Item>
                                </Descriptions.Item>
                                <Descriptions.Item label="用户名*">
                                    <Form.Item name="userName" rules={[{required: true, message: '请输入用户名'}]} style={{ margin: 0 }}>
                                        <Input size="small" placeholder="必填：用户名"/>
                                    </Form.Item>
                                </Descriptions.Item>
                                <Descriptions.Item label="连接类型*">
                                    <Form.Item name="connectType" initialValue={catalog?.connectType || 'SERVICE_NAME'} rules={[{required: true, message: '请选择连接类型'}]} style={{ margin: 0 }}>
                                        <Radio.Group>
                                            <Radio value="SERVICE_NAME">ServiceName</Radio>
                                            <Radio value="SID">SID</Radio>
                                        </Radio.Group>
                                    </Form.Item>
                                </Descriptions.Item>
                                <Descriptions.Item label="数据库版本">{catalog?.databaseVersion || '-'}</Descriptions.Item>
                                <Descriptions.Item label="Doris Catalog 名称*">
                                    <Form.Item name="dorisCatalogName" rules={[{required: true, message: '请输入 Doris Catalog 名称'}]} style={{ margin: 0 }}>
                                        <Input size="small" placeholder="必填：Doris Catalog 名称"/>
                                    </Form.Item>
                                </Descriptions.Item>
                                <Descriptions.Item label="默认系统编码*">
                                    <Form.Item name="defaultSystemCode" rules={[{required: true, message: '请输入默认系统编码'}]} style={{ margin: 0 }}>
                                        <Input size="small" placeholder="必填：默认系统编码"/>
                                    </Form.Item>
                                </Descriptions.Item>
                                <Descriptions.Item label="状态">{catalog?.enabled ? <Tag color="green">已启用</Tag> :
                                    <Tag color="red">未启用</Tag>}</Descriptions.Item>
                            </Descriptions>
                        </Form>
                        <Space style={{ marginTop: 8 }}>
                            <Button size="small" onClick={() => testEditing('server')} loading={editingTesting.server}>测试服务器</Button>
                            <Button size="small" onClick={() => testEditing('jdbc')} loading={editingTesting.jdbc}>测试JDBC</Button>
                            <Button size="small" onClick={() => testEditing('doris')} loading={editingTesting.doris}>测试Doris</Button>
                            <Button size="small" type="primary" onClick={submitEdit} loading={saving}>保存</Button>
                            <Button size="small" onClick={() => setEditing(false)}>取消</Button>
                        </Space>
                    </>
                )}
            </Card>

            {/* 数据库列表 */}
            <Card size="small" title={<Space><DatabaseOutlined/><span>数据库列表</span></Space>}
                  extra={<Space>
                      <Input.Search allowClear placeholder="搜索数据库" size="small" value={dbSearch}
                                    onChange={(e) => setDbSearch(e.target.value)} style={{ width: 200 }} />
                      <Button size="small" icon={<CloudServerOutlined/>} onClick={handleSync}
                              loading={syncing}>同步目录</Button>
                      <Button size="small" icon={<ReloadOutlined/>} onClick={loadDatabases}
                              loading={loadingDB}>刷新</Button>
                  </Space>}>
                <Table
                    size="small"
                    rowKey={(r) => (r as any)?.name ?? (r as any)?.databaseName ?? JSON.stringify(r)}
                    dataSource={filteredDatabases as any}
                    pagination={false}
                    columns={databaseColumns as any}
                />
            </Card>

            {/* 编辑弹窗移除，改为内联编辑 */}
        </div>
    )
}